#ifndef CUSTOM_LIGHTING_INCLUDED
#define CUSTOM_LIGHTING_INCLUDED


float3 GetIncomingLight(Surface surface,Light light)
{
	return saturate( dot(surface.normal,light.direction) * light.attenuation ) * light.color;
}

float SpecularStrength(Surface surface,BRDF brdf,Light light)
{
	float3 h = SafeNormalize(light.direction + surface.viewDirection);
	float nh2 = Square(saturate(dot(surface.normal,h)));
	float lh2 = Square(saturate(dot(light.direction,h)));
	float r2 = Square(brdf.roughness);
	float d2 = Square(nh2 * (r2 - 1.0)+1.0001);
	float n = brdf.roughness * 4.0 + 2.0;
	return r2/ (d2 * max(0.1,lh2) * n);
}
float3 DrectBRDF(Surface surface,BRDF brdf,Light light)
{
	float specularStrength = SpecularStrength(surface,brdf,light);
	return brdf.diffuse + brdf.specular * specularStrength;
}

float3 IndirectBRDF(Surface surface,BRDF brdf,float3 diffuse,float3 specular)
{
	float fresnelStrength = surface.fresnelStrength * Pow4(1.0 - saturate(dot(surface.normal,surface.viewDirection)));
	float3 refelction = specular * lerp(brdf.specular,brdf.fresnel,fresnelStrength);
	refelction /= brdf.roughness * brdf.roughness + 1.0;
	float3 indirect = diffuse * brdf.diffuse + refelction;
	indirect *= surface.occlusion;
	return indirect;
}


float3 GetLighting(Surface surface,BRDF brdf,Light light)
{
	//float3 surfaceColor = surface.color;
	//float3 surfaceColor = brdf.diffuse;
	float3 surfaceColor = DrectBRDF(surface,brdf,light);
	return GetIncomingLight(surface,light) * surfaceColor ;
}


float3 GetLighting(Surface surface,BRDF brdf,GI gi)
{
	ShadowData shadowData = GetShadowData(surface);
	shadowData.shadowMask = gi.shadowMask;
	//return gi.shadowMask.shadows.rgb;

	//float3 color =0.0;
	//float3 color = gi.diffuse * brdf.diffuse;
	float3 color = IndirectBRDF(surface,brdf,gi.diffuse,gi.specular);
	int lightCount = GetDirectionalLightCount();
	for(int i=0; i < lightCount; i++)
	{
		Light light = GetDirectionalLight(i,surface,shadowData);
		color += GetLighting(surface,brdf,light);
	}
	return color;
}
#endif